#-*- coding: utf8 -*-
from tutor.script import *
from tutor.plugin.maple import *

# meta-informação
meta(author       = 'Fábio Mendes',
     creationdate = datetime(2010, 10, 24),
     status       = 'testing',
     difficulty   = 'hard',
     time         = 10,
     itemtype     = 'test')

# bolinha vs serra: calcular a distância entre uma trajetória parabólica e
# um círculo
x_, y_ = M.x_, M.y_

# sorteia parâmetros da parábola e raio
raio = M.sqrt(oneof(1,2,3,4,5,8))
a = randint(int(raio) + 1, 6) 
b = oneof(1, -1) * oneof(M(1)/2, 1, 2, 3)
c = oneof(M(1)/4, M(1)/3, M(1)/2, 1, M(3)/2, 2)

# equação da parábola e da circunferência
y_parabola = a + b*x - c*x**2
eq_parabola = y == y_parabola
eq_circulo = x_**2 + y_**2 == raio**2

# verifica se não existe solução simultânea para os dois problemas
sol = M.fsolve(y + c*y**2 == c*raio**2 + a + b*M.sqrt(raio**2 - y**2))
assert bool(M.op(0, sol) == M.fsolve), 'solução encontrada: y = %s' % sol 
 
sol = M.fsolve(y + c*y**2 == c*raio**2 + a - b*M.sqrt(raio**2 - y**2))
assert bool(M.op(0, sol) == M.fsolve), 'solução encontrada: y = %s' % sol 

# multiplicadores de Lagrange e função de vínculo
A = M.alpha
B = M.beta
d2 = (x-x_)**2 + (y-y_)**2
func = d2 - A * (y_parabola - y) - B * (x_**2 + y_**2 - raio**2)

# monta o sistema de equações
eq1 = diff(func, x)
eq2 = diff(func, y)
eq3 = diff(func, x_)
eq4 = diff(func, y_)

# resolve sistema de equações
sol = M.solve([eq1, eq2, eq3, eq4], [x, y, x_, y_])[0]
sol = [ M.rhs(eq) for eq in sol ]
x0, y0, x_0, y_0 = sol

# substitui nos vínculos
eqv1 = x_0**2 + y_0**2 == raio**2
eqv2 = y0 == subs(x==x0, y_parabola)
sol = M.solve([eqv1, eqv2], [A, B])
sol = [ M.simplify(M.rhs(eq)) for eq in sol[0] ]
sol = [ float(M.evalf(obj)) for obj in sol ]
A0, B0 = sol
x0f, y0f, x_0f, y_0f = subs(A==A0, B==B0, [x0, y0, x_0, y_0])
print('Multiplicadores de Lagrange: alpha=%s e beta=%s' % (A0, B0))

question(u'\\textbf{(Desafio)} Um objeto leve descreve uma trajetória parabólica dada por\n\n'
          '      $$y = ', y_parabola, '.$$\n\n'
          'Calcule a distância mínima que o objeto atinge de uma esfera\n'
          'oca de raio $', raio, '$ com o centro na origem.\n\n'
          '\\textbf{Observação:} A resposta é dada em\n' 
          'função dos multiplicadores de Lagrange, que não podem ser calculados\n'
          'analiticamente. $\\alpha$ e $\\beta$ são, respectivamente, os \n'
          'multiplicadores de Lagrange para os vínculos\n'
          'sobre a parábola e sobre a circunferência.\n\n'
          '\\textbf{Dica:} Minimize a distância ao quadrado. Talvez não seja\n' 
          'necessário resolver todas equações para calcular a distância!\n')
multiplechoice()

# choice: (a)
choice_eq(1, B**2 * raio**2)
explanation('Escolha correta!') 

# choice: (b)
ans = expand(b**2/(1 + B * (c-1))**2 + 1/(1-B)**2)
ans = simplify(ans)
ans = B**2/4 * ans
choice_eq(0, ans)
explanation(u"Deve existir um conjunto de variáveis diferentes $x$, $y$ e $x'$\n"
            "$y'$ para representar os pontos no círculo e na parábola. Sendo assim,\n"
            "a distância ao quadrado entre as duas superfícies ficaria \n"
            "$d^2 = (x-x')^2 + (y-y')^2$.") 

# choice: (c)
ans = expand(b**2/(1 + A*c - B)**2 + 1/(1-B)**2)
ans = simplify(ans)
ans = A**2/4 * ans
choice_eq(0, ans)
explanation(u"Deve existir um conjunto de variáveis diferentes $x$, $y$ e $x'$\n"
            "$y'$ para representar os pontos no círculo e na parábola. Sendo assim,\n"
            "a distância ao quadrado entre as duas superfícies ficaria \n"
            "$d^2 = (x-x')^2 + (y-y')^2$.")

# choice: (d)
ans = A**2 * raio**2 + 2 * raio * B 
choice_eq(0, ans)
explanation('Este resultado provavelmente é um chute!') 

# choice: (e)
choice(0, '$0$, o objeto colide em cheio com a circunferência!')
explanation('Para haver colisão deve existir algum ponto que satisfaça\n' 
            'simultaneamente a equação da parábola mostrada no enunciado e a\n'
            'equação do círculo $x^2 + y^2 = ', raio**2, '$') 

end()